package com.dwxt.community.aiequipment.util;

import com.dwxt.common.base.*;
import com.dwxt.community.exception.*;
import org.slf4j.*;

import java.io.*;
import java.text.*;

/**
 * @program: intelligentcity
 * @description: 进制互转工具类
 * @author
 * @create: 2020/04/15
 */
public class DataHandler {
    private static Logger log = LoggerFactory.getLogger(DataHandler.class);

    private static final char HexCharArr[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};

    private static final String HexStr = "0123456789abcdef";


    /**
     *    double 拆分为底高位
     */
    public static int[] splitDouble2LowHighs(double data) {
        int[] splitLowAndHigh = new int[2];
        int datas = (int)(data * 10.0D);
        splitLowAndHigh[0] = datas & 255;
        splitLowAndHigh[1] = datas >> 8;
        return splitLowAndHigh;
    }
    /**
     * long拆成4个byte
     *
     * @param data
     * @return
     */
    public static int[] splitLong2FourLowHigh(long data) {
        return new int[]{(int)(data & 255L), (int)(data >> 8 & 255L), (int)(data >> 16 & 255L), (int)(data >> 24 & 255L)};
    }
    /**
     * 验证CRC
     *
     * @param deviceData
     * @return
     */
    public static boolean crcDeviceData(int[] deviceData) {
        int temp = 0xffff, temp1;
        for (int i = 0; i < deviceData.length - 2; i++) {
            temp ^= deviceData[i];
            for (int j = 0; j < 8; j++) {
                temp1 = temp;
                temp >>= 1;
                if ((temp1 & 0x0001) == 0x0001) {
                    temp ^= 0xa001;
                }
            }
        }
        int _crc = deviceData[deviceData.length - 1] << 8 | deviceData[deviceData.length - 2];
        return _crc == temp;
    }


    /**
     * 构建CRC数组
     *
     * @param deviceData
     * @return
     */
    public static int[] buildCrcArr(int[] deviceData) {
        int crc = bulidCrc(deviceData);
        deviceData[deviceData.length - 1] = high(crc);
        deviceData[deviceData.length - 2] = low(crc);
        return deviceData;
    }

    /**
     * 回复数据 CRC 构建
     *
     * @param data
     * @return
     */
    public static int bulidCrc(int[] data) {

        int temp = 0xffff, temp1;
        for (int i = 0; i < data.length - 2; i++) {
            temp ^= data[i];
            for (int j = 0; j < 8; j++) {
                temp1 = temp;
                temp >>= 1;
                if ((temp1 & 0x0001) == 0x0001) {
                    temp ^= 0xa001;
                }
            }
        }
        return temp;
    }

    /**
     * 截取int数组 包含首尾
     *
     * @return
     */
    public static int[] subInts(int[] data, int str, int end) {
        int len = end - str + 1;
        int[] ints = new int[len];
        for (int i = 0; i < len; i++) {
            ints[i] = data[str++];
        }
        return ints;
    }

    /**
     * 截取byte数组 包含首尾
     *
     * @return
     */
    public static byte[] subBytes(byte[] data, int str, int end) {
        int len = end - str + 1;
        byte[] bytes = new byte[len];
        for (int i = 0; i < len; i++) {
            bytes[i] = data[str++];
        }
        return bytes;
    }

    /**
     * int数组转byte数组
     *
     * @param resInts
     * @return
     */
    public static byte[] toByteArray(int[] resInts) {

        try (ByteArrayOutputStream baos = new ByteArrayOutputStream();
             DataOutputStream dos = new DataOutputStream(baos)) {
            for (int resInt : resInts) {
                dos.writeByte(resInt);
            }
            return baos.toByteArray();
        } catch (IOException e) {
            log.error(e.getMessage());
            e.printStackTrace();
            return new byte[]{};
        }

    }

    /**
     * 将字节数组转为十六进制字符串
     * @return
     */
    public static String encodeHexStr(byte[] btArr) {
        char strArr[] = new char[btArr.length * 2];
        int i = 0;
        for (byte bt : btArr) {
            strArr[i++] = HexCharArr[bt >>> 4 & 0xf];
            strArr[i++] = HexCharArr[bt & 0xf];
        }
        return new String(strArr);
    }

    /**
     * 十六进制字符串转字节数组
     *
     * @param hexStr
     * @return
     */
    public static byte[] hexToByteArr(String hexStr) {
        char[] charArr = hexStr.toCharArray();
        byte btArr[] = new byte[charArr.length / 2];
        int index = 0;
        for (int i = 0; i < charArr.length; i++) {
            int highBit = HexStr.indexOf(charArr[i]);
            int lowBit = HexStr.indexOf(charArr[++i]);
            btArr[index] = (byte) (highBit << 4 | lowBit);
            index++;
        }
        return btArr;
    }

    /**
     * 获取低位
     */
    public static int low(int src) {
        return src & 0xff;
    }

    /**
     * 获取高位
     */
    public static int high(int src) {
        return src >> 8;
    }


    /**
     * 保留浮点数小数点后面几位
     *
     * @param f      浮点数
     * @param format 浮点数的格式
     * @return
     */
    public static String formatFloat(float f, String format) {
        DecimalFormat df = new DecimalFormat(format);
        return df.format(f);
    }

    /**
     * 将两个字节拼接还原成有符号的整型数据
     * 数据域中的数据都按小端存储，示例：数据0x1234，则Byte0为0x34,Byte1为0x12
     */
    public static int unionLowHigh(int low, int high) {
        return Math.max(high << 8 | low, 0);
    }

    /**
     * byte数组转int数组
     *
     * @param bytes
     * @return
     */
    public static int[] toIntArray(byte[] bytes) {
        int[] ints = new int[bytes.length];
        for (int i = 0; i < bytes.length; i++) {
            if (bytes[i] < 0) {
                ints[i] = 0xff & bytes[i];
            } else {
                ints[i] = bytes[i];
            }
        }
        return ints;
    }

    /**
     * int数组转char数组
     * @return
     */
    public static String toCharArrayStr(int[] ints) {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < ints.length; i++) {
            sb.append((char) ints[i]);
        }
        return sb.toString();
    }
    /**
     * 数组替换  包含首不包含尾
     */
    public static int[] arrReplace(int[] src , int str , int end , int[] target) throws AiEquipemntException {
        if ((end - str)!=target.length || target.length > src.length){
            throw new AiEquipemntException(BaseResult.build(-1,"无法替换",null));
        }
        int j = str;
        for (int i = 0; i < end-str ; i++) {
            src[j++] = target[i];
        }
        return src;
    }
}
